from typing import Any, Dict, Generic, List, Optional

from pydantic import ConfigDict, Field

from app.schemas.base import BaseSchema, T


def exclude_empty_values(data: Dict[str, Any]) -> Dict[str, Any]:
    """
    递归移除值为 None、""、[]、{} 的字段（可根据需要调整）
    """
    result = {}
    for k, v in data.items():
        if isinstance(v, dict):
            cleaned = exclude_empty_values(v)
            if cleaned:  # 只有非空字典才保留
                result[k] = cleaned
        elif isinstance(v, list):
            if v:  # 非空列表才保留
                result[k] = v
        elif v is None or v == "":
            continue  # 跳过 None 和空字符串
        else:
            result[k] = v
    return result


class Option(BaseSchema, Generic[T]):
    """
    下拉选项对象

    用于表示前端下拉选择框的选项数据

    Attributes:
        value: 选项的值
        label: 选项的标签
        tag: 标签类型（可选）
        children: 子选项列表（可选）
    """

    model_config = ConfigDict(
        validate_by_name=True, from_attributes=True, use_enum_values=True, extra="ignore", populate_by_name=True
    )

    value: T = Field(..., alias="value", description="选项的值")
    label: str = Field(..., alias="label", description="选项的标签")
    tag: Optional[str] = Field(default=None, alias="tag", description="标签类型")
    children: Optional[List["Option[T]"]] = Field(default=None, alias="children", description="子选项列表")

    # def model_dump(self, **kwargs) -> Dict[str, Any]:
    #     data = super().model_dump(**kwargs)
    #     return exclude_empty_values(data)

    def __init__(
        self, value: T, label: str, tag: Optional[str] = None, children: Optional[List["Option[T]"]] = None, **kwargs
    ):
        """
        初始化选项对象

        Args:
            value: 选项的值
            label: 选项的标签
            tag: 标签类型（可选）
            children: 子选项列表（可选）
        """
        super().__init__(value=value, label=label, tag=tag, children=children, **kwargs)

    @classmethod
    def create_simple(cls, value: T, label: str) -> "Option[T]":
        """
        创建简单选项（无标签和子选项）

        Args:
            value: 选项的值
            label: 选项的标签

        Returns:
            Option[T]: 创建的选项对象
        """
        return cls(value=value, label=label)

    @classmethod
    def create_with_tag(cls, value: T, label: str, tag: str) -> "Option[T]":
        """
        创建带标签的选项

        Args:
            value: 选项的值
            label: 选项的标签
            tag: 标签类型

        Returns:
            Option[T]: 创建的选项对象
        """
        return cls(value=value, label=label, tag=tag)

    @classmethod
    def create_with_children(cls, value: T, label: str, children: List["Option[T]"]) -> "Option[T]":
        """
        创建带子选项的选项（用于级联选择）

        Args:
            value: 选项的值
            label: 选项的标签
            children: 子选项列表

        Returns:
            Option[T]: 创建的选项对象
        """
        return cls(value=value, label=label, children=children)


# 常用类型别名
StringOption = Option[str]
IntOption = Option[int]
BoolOption = Option[bool]
